﻿/****************************** Module Header ******************************\
 * Module Name:  FormSearchBar.cs
 * Module Version:  2.0.1 (2013-1-25)
 * Copyright (c) AnyEB.Com (14507247@qq.com)
 * 
 * This class is used to process the FormSearchBar.
 * #2013-1-25 2.0.1 新增右键菜单功能
 * #2013-1-22 2.0.0 在原来基础上新增数据类型自动转换为控件的功能
 * #2012-10-18 1.0.0 提供基本文本搜索的功能
 * 
 * This source is subject to the GPL License.
 * See http://www.gnu.org/licenses/gpl.html.
 * All other rights reserved.
 * 
 * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
 * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/
using System;
using System.Data;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

namespace UCL.Forms.Components
{
    /// <summary>
    /// 高级搜索
    /// </summary>
    public partial class SoSearchAdvancedTable : Form, ISearchAdvanceForm
    {
        /// <summary>
        /// 获取或设置搜索方法
        /// </summary>
        public Action<string> SearchHandler { get; set; }

        /// <summary>
        /// 获取或设置预览方法
        /// </summary>
        public Action<string> PreviewHandler { get; set; }

        /// <summary>
        /// 获取或设置统计数据文本
        /// </summary>
        public string SummaryText { set { ucButtons1.SummaryText = value; } }

        /// <summary>
        /// 获取或设置布尔值字段的显示模式
        /// <para>CHECKBOX | COMBOBOX</para>
        /// </summary>
        public string BooleanFieldMode { get; set; }

        /// <summary>
        /// 是否启用调试模式
        /// </summary>
        public bool IsDebug { get; set; }

        /// <summary>
        /// 获取或设置搜索字段
        /// <para>ID | Name | Type | Default | DataSource</para>
        /// <para>Type支持：text,date,bool,group,其中,group格式:value=name&value=name</para>
        /// <example>
        /// DataTable dt = new DataTable();
        /// dt.Rows.Add("Text1", "文本1", "text", "默认值1");
        /// dt.Rows.Add("Date2", "日期2", "date", "2013-1-21");
        /// dt.Rows.Add("Bool5", "布尔3", "bool", "false");
        /// dt.Rows.Add("Group6", "下拉4", "group", "0","0=未确认&1=待发货&14=未发货,退回&(7,10,16,17,19)=确认不通过,已退回");
        /// </example>        
        /// </summary>
        public DataTable Fields { get; set; }

        /// <summary>
        /// 是否复合组合查询模式
        /// </summary>
        public bool IsCompositeGroup
        {
            get
            {
                return colLeft.Visible;
            }
            set
            {
                colLeft.Visible = value;
                colRight.Visible = value;
            }
        }

        DateTimePicker dtp = new DateTimePicker() { Visible = false };
        ComboBox cbb = new ComboBox() { Visible = false };
        CheckBox chk = new CheckBox() { Visible = false };

        public SoSearchAdvancedTable()
        {
            InitializeComponent();

            dtp.Format = DateTimePickerFormat.Custom;
            dtp.CustomFormat = "yyyy-MM-dd";
            dtp.CloseUp += new EventHandler(dtp_CloseUp);
            cbb.SelectedIndexChanged += new EventHandler(cbb_SelectedIndexChanged);
            chk.Click += new EventHandler(chk_Click);
            dgvGroup.Controls.Add(dtp);
            dgvGroup.Controls.Add(cbb);
            dgvGroup.Controls.Add(chk);

            FormsSkinHelper fsh = new FormsSkinHelper(new FormsSkinOfBlue());
            fsh.SetSkin(this.Controls);

        }
        #region 自定义数据控件事件

        private void dtp_CloseUp(object s, EventArgs e)
        {
            dgvGroup.CurrentCell.Value = dtp.Text;
            HideAllControls();
        }
        private void cbb_SelectedIndexChanged(object s, EventArgs e)
        {
            dgvGroup.CurrentCell.Value = cbb.GetSelectedValue();
            HideAllControls();
        }
        private void chk_Click(object s, EventArgs e)
        {
            dgvGroup.CurrentCell.Value = chk.Checked;
            HideAllControls();
        }
        #endregion

        private void FormSearchAdvanced_Load(object sender, EventArgs e)
        {
            colField.SetDataSource(Fields);
            colOperate.SetDataSource(ListItemTable.New<string, string>().Add("=", "等于").Add("<", "小于").Add(">", "大于").Add("<=", "小于等于").Add(">=", "大于等于").Add("<>", "不等于").Add("like", "包含").Add("in", "并值").ToTable());
            colContactor.SetDataSource(ListItemTable.New<string, string>().Add("and", "并且").Add("or", "或者").ToTable());

            // 是否显示预览按钮
            ucButtons1.PreviewVisible = PreviewHandler != null;
            ucButtons1.BtnPreview.Click += new EventHandler(btnPreview_Click);
            ucButtons1.BtnReset.Click += new EventHandler(btnReset_Click);
            ucButtons1.BtnExit.Click += new EventHandler(btnExit_Click);
            ucButtons1.BtnRun.Click += new EventHandler(btnRun_Click);
        }

        private void btnRun_Click(object sender, EventArgs e)
        {
            string sql = GetSearchSql();
            if (SearchHandler != null && !string.IsNullOrEmpty(sql)) SearchHandler(sql);
        }

        /// <summary>
        /// 获取搜索字符串
        /// </summary>
        /// <returns></returns>
        /// <remarks>2014-4-1 by sutroon</remarks>
        public string GetSearchSql()
        {
            int pairCount = 0;
            StringBuilder sb = new StringBuilder(), sbErr = new StringBuilder();
            object v; string voperator, strv;
            int rowCount = dgvGroup.Rows.Count;
            foreach (DataGridViewRow r in dgvGroup.Rows)
            {
                if (r.IsNewRow) break;
                // (
                if (colLeft.Visible)
                {
                    v = r.Cells["colLeft"].Value;
                    if (v != null && (bool)v)
                    {
                        pairCount -= 1;
                        sb.Append("(");
                    }
                }
                // field
                v = r.Cells["colField"].Value;
                if (v == null)
                {
                    sbErr.AppendLine("搜索字段不能为空!");
                    break;
                }
                sb.AppendFormat(" {0} ", v);
                // operate
                v = r.Cells["colOperate"].Value;
                if (v == null)
                {
                    sbErr.AppendLine("操作符不能为空!");
                    break;
                }
                voperator = r.Cells["colOperate"].Value.ToString();
                sb.AppendFormat(" {0} ", v);
                // value
                v = r.Cells["colValue"].Value;
                if (v == null)
                {
                    sbErr.AppendLine("搜索的值不能为空!");
                    break;
                }
                strv = v.ToString().Trim();
                if (voperator == "like")
                {
                    // 自定义模糊搜索：^{word}如：^prefix%
                    if (strv.Length > 0 && strv[0] == '^')
                    {
                        sb.AppendFormat(" '{0}' ", strv.Substring(1).Replace("'", ""));
                    }
                    else
                    {
                        sb.AppendFormat(" '%{0}%' ", strv.Replace("'", ""));
                    }
                }
                else
                {
                    sb.AppendFormat(" '{0}' ", strv.Replace("'", ""));
                }
                // )
                if (colRight.Visible)
                {
                    v = r.Cells["colRight"].Value;
                    if (v != null && (bool)v)
                    {
                        pairCount += 1;
                        sb.Append(")");
                    }
                }
                // contactor
                v = r.Cells["colContactor"].Value;
                if (v == null && r.Index < rowCount - 2)
                {
                    sbErr.AppendLine("条件连接方式不能为空!");
                    break;
                }
                if (r.Index == rowCount - 2) break;
                sb.AppendFormat(" {0} ", v);
            }
            if (IsDebug) MessageBox.Show(sb.ToString());
            if (sbErr.Length > 0)
            {
                MessageBox.Show(sbErr.ToString());
                return string.Empty;
            }
            if (pairCount != 0)
            {
                MessageBox.Show("括号没闭合,请检查!");
                return string.Empty;
            }
            return sb.ToString();
        }

        private void btnReset_Click(object sender, EventArgs e)
        {
            HideAllControls();
            this.dgvGroup.Rows.Clear();
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnPreview_Click(object sender, EventArgs e)
        {
            string sql = GetSearchSql();
            if (PreviewHandler != null && !string.IsNullOrEmpty(sql)) PreviewHandler(sql);
        }

        private void dgvGroup_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex == dgvGroup.NewRowIndex) return;
            if (e.ColumnIndex == colRemove.Index)
            {
                if (dgvGroup.Rows.Count == 1) return;
                dgvGroup.Rows.RemoveAt(e.RowIndex);
            }
            if (Fields.Columns.Count < 3) return;
            if (e.ColumnIndex == colValue.Index)
            {
                HideAllControls();
                DataRow r = Fields.AsEnumerable().SingleOrDefault(a => a.Field<string>("ID") == dgvGroup.CurrentCell.OwningRow.Cells["colField"].Value.ToString());
                Rectangle _Rectangle = dgvGroup.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true); //得到所在单元格位置和大小
                Size size = new Size(_Rectangle.Width, _Rectangle.Height); //把单元格大小赋给控件
                Point location = new Point(_Rectangle.X, _Rectangle.Y); //把单元格位置赋给控件
                switch (r["Type"].ToString())
                {
                    case "date":
                        dtp.Size = size;
                        dtp.Location = location;
                        dtp.Visible = true;
                        return;
                    case "group":
                        cbb.DataSource = r["DataSource"].ToString().ToDataTable();
                        cbb.DisplayMember = "col1";
                        cbb.ValueMember = "col0";
                        cbb.Size = size;
                        cbb.Location = location;
                        cbb.Visible = true;
                        return;
                    case "bool":
                        if (BooleanFieldMode == "COMBOBOX")
                        {
                            cbb.DataSource = "1=是&0=否".ToDataTable();
                            cbb.DisplayMember = "col1";
                            cbb.ValueMember = "col0";
                            cbb.Size = size;
                            cbb.Location = location;
                            cbb.Visible = true;
                        }
                        else
                        {
                            chk.Size = size;
                            chk.Location = location;
                            chk.Visible = true;
                        }
                        return;
                }
                return;
            }
            HideAllControls();
        }
        private void HideAllControls()
        {
            dtp.Visible = false;
            cbb.Visible = false;
            chk.Visible = false;
        }
    }
}
